package com.cs.framework.jdbc.mybatis3.session;

import java.io.IOException;
import java.util.Properties;
import java.util.Set;

import javax.sql.DataSource;

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.core.io.Resource;

import com.cs.framework.common.util.IOUtils;
import com.cs.framework.common.util.StringUtils;
import com.cs.framework.jdbc.mybatis3.builder.ConfigBuilder;
import com.cs.framework.jdbc.mybatis3.builder.SqlBuilder;
import com.cs.framework.jdbc.mybatis3.executor.SelectExecutor;
import com.cs.framework.jdbc.mybatis3.utils.MyBatisConstant;

/**
 * 仅提供查询的Session工厂
 * 
 * @author hedongzhou
 * 
 */
public class BaseSelectSessionFactory implements SelectSessionFactory {

	/**
	 * 数据源
	 */
	protected DataSource dataSource;

	/**
	 * mybatis属性配置文件路径
	 */
	protected String propertiesPath;

	/**
	 * 配置信息
	 */
	protected Configuration configuration;

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public String getPropertiesPath() {
		return propertiesPath;
	}

	public void setPropertiesPath(String propertiesPath) {
		this.propertiesPath = propertiesPath;
	}

	public Configuration getConfiguration() {
		return configuration;
	}

	public void setConfiguration(Configuration configuration) {
		this.configuration = configuration;
	}

	/**
	 * 构建工厂
	 */
	public void build(String id, String sqlPath) throws Exception {
		if (configuration == null) {
			ConfigBuilder configBuilder = new ConfigBuilder(dataSource);
			configuration = configBuilder.build(id);
		}

		builderSql(sqlPath);
		builderTypeHander();
	}

	/**
	 * 创建SQL
	 * 
	 * @param sqlPath
	 */
	public void builderSql(String sqlPath) {
		SqlBuilder sqlXMLBuilder = new SqlBuilder(configuration);
		sqlXMLBuilder.build(sqlPath);
	}

	/**
	 * 创建类型转换器
	 * 
	 * @throws IOException
	 */
	public void builderTypeHander() throws Exception {
		if (StringUtils.isNotBlank(propertiesPath)) {
			Resource res = IOUtils.loadOneResource(propertiesPath);

			// 判断是否存在属性配置文件
			if (res != null) {
				// 获取属性配置信息
				Properties myBatisProperties = new Properties();
				myBatisProperties.load(res.getInputStream());

				TypeAliasRegistry typeAliasRegistry = configuration.getTypeAliasRegistry();
				TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
				Set<Object> keys = myBatisProperties.keySet();

				for (Object key : keys) {
					String keyStr = (String) key;

					if (keyStr.startsWith(MyBatisConstant.TYPE_HANDLER_PRO)) {
						typeHandlerRegistry.register(typeAliasRegistry.resolveAlias(StringUtils.replace(keyStr, MyBatisConstant.TYPE_HANDLER_PRO, "")), typeAliasRegistry.resolveAlias(myBatisProperties.getProperty(keyStr)));
					}
				}
			}
		}
	}

	/**
	 * 打开Session
	 * 
	 * @return
	 */
	public SelectSession openSession() {
		return new BaseSelectSession(new SelectExecutor(configuration, dataSource));
	}

}
